Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

【Hackathon 6th Article No.7】0 维 tensor 的使用指南 #860

Merged
merged 5 commits into from
Apr 29, 2024

Conversation

AndSonder
Copy link
Contributor

@AndSonder AndSonder commented Apr 9, 2024

Copy link

paddle-bot bot commented Apr 9, 2024

你的PR提交成功,感谢你对开源项目的贡献!
请检查PR提交格式和内容是否完备,具体请参考示例模版
Your PR has been submitted. Thanks for your contribution!
Please check its format and content. For this, you can refer to Template and Demo.


这里vector是一个一维张量,有3个元素,对应shape为[3]。

以上从数学角度上区分了 0-d Tensor 和 1-d Tensor,在物理学中,标量和向量是两个基本的物理量概念。标量只有一个数值, 没有方向; 而向量除了数值外, 还附带一个确定的方向。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

数学上叫 数量、向量
物理上叫 标量、矢量


0-d Tensor对应着物理学中的标量概念。一个 0-d Tensor, 如 3.14、2.78 等, 仅仅表示一个单一的数值, 没有任何其他维度的信息。它可以表示一些简单的物理量,如温度、质量、电荷等。

而 1-d Tensor 则对应着向量的概念。即使只有1个元素, 如 [5.0], 它也不是一个纯标量, 而是一个有确定方向的向量。这个方向在物理意义上可能对应 xyz 三个空间坐标中的某个轴, 或者表示力、速度、电场强度等有方向性的物理量。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

xyz 三个空间坐标中的某个轴 应该是一个数学概念


x = torch.tensor(3.14)
out = torch.stack([x, x])
print(out.shape) # 输出 torch.Size([2]) 没有新增维度
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

torch.stack会出现升维情况,这个例子再看看

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

torch.stack会出现升维情况,这个例子再看看

这里主要想讲之前paddle不支持0-d tensor的时候,stack api 和 torch 行为不一致的问题,我对描述又修改了一下


### 2.1 潜在的纬度错误

标量张量与仅含有一个元素的向量张量容易造成混淆,它们的元素个数相同,但在数学定义上完全不同。若将其形状表示为 `shape=[1]`,则无法区分标量张量和向量张量,这与数学语义和行业通用的计算规则相悖,可能导致模型出现意料之外的错误,并增加开发调试成本。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

无法区分标量和向量


对于所有的 elementwise 一元运算(如 tanh、relu 等)和二元运算 (如 add、sub、multiply 等), 理应支持 0-d Tensor 作为输入或通过广播机制与高维Tensor进行计算。同时, 复合运算如 Linear(相当于matmul+add)也应支持 0维输入。

Paddle 已经支持了大部分逐元素计算类的运算:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个应该是 全部


# gather
idx = paddle.to_tensor([0, 1])
y = paddle.gather(x, idx, axis=0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

上面有y,下面也有y,容易混乱,是否每个例子单独介绍

print(y.shape) # [2, 3, 2, 4]
```

在这个例子中, y 是 x 的一个标量索引, 因此适合用 0-d Tensor 来表示。z 和 w 是 x 的切片索引, 因此适合用 1-d Tensor 来表示。最后, y 是 x 的 gather 操作, 输出是一个 4 维 Tensor, 因此不适合用 0-d Tensor 来表示。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不是 不适合用0-d Tensor来表示,而是本身就不是0d。这几个例子没看懂是要说明什么问题

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不是 不适合用0-d Tensor来表示,而是本身就不是0d。这几个例子没看懂是要说明什么问题

已重写


在深度学习框架中,0维Tensor虽然形式简单,但具有重要的概念意义和实际应用价值。它不仅对应数学和物理上的标量概念,也是各种标量计算和控制流程的基础表示形式。

支持 0-d Tensor的使用,可以让框架更加贴合数学规范,让代码更加简洁优雅。同时,它也是实现很多实用功能的基石。框架要避免在处理0维和1维Tensor时产生行为分歧,尽量与其他主流框架保持一致,方便模型和算子在不同框架间的移植。当下 Paddle 已经支持了大部分适合使用 0-d Tensor 的场景, 让用户能够方便地使用 0-d Tensor。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

当下 Paddle框架中已经全面支持0-D Tensor,并实际上已成为后续新增算子的开发规范,

@AndSonder
Copy link
Contributor Author

已经都按照要求修改啦,麻烦研发老师再看看 ~

@AndSonder AndSonder requested a review from zhwesky2010 April 17, 2024 08:49
@zhwesky2010
Copy link
Contributor

已经都按照要求修改啦,麻烦研发老师再看看 ~

这边没有看到有新的提交,是不是修改了没提交成功

@AndSonder
Copy link
Contributor Author

已经都按照要求修改啦,麻烦研发老师再看看 ~

这边没有看到有新的提交,是不是修改了没提交成功

抱歉,应该是网络问题没push成功,现在可以看到了

@@ -29,11 +29,11 @@ print(vector, vector.shape)

这里vector是一个一维张量,有3个元素,对应shape为[3]。

以上从数学角度上区分了 0-d Tensor 和 1-d Tensor,在物理学中,标量和向量是两个基本的物理量概念。标量只有一个数值, 没有方向; 而向量除了数值外, 还附带一个确定的方向。
以上从数学角度上区分了 0-d Tensor 和 1-d Tensor,在物理学中,标量和矢量是两个基本的物理量概念。标量只有一个数值, 没有方向; 而矢量除了数值外, 还附带一个确定的方向。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

全文的中文标点,和英文标点区分一下。统一成:中文标点符号

@@ -53,10 +53,10 @@ import torch

x = torch.tensor(3.14)
out = torch.stack([x, x])
print(out.shape) # 输出 torch.Size([2]) 没有新增维度
print(out.shape) # 输出 torch.Size([2]) 没有新增维度,符合预期
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0D升为1D,符合预期

```

如果 Paddle 不支持 0-d Tensor 而是直接用 1-d Tensor 来表示, 就需要额外判断 x 是否为 1D,是就需要补 squeeze 来矫正结果以对齐 pytorch,不是就可和 Pytorch 相同。
如果 Paddle 不支持 0-d Tensor 而是直接用 1-d Tensor 来表示, 就需要额外判断 x 是否为 1D,是就需要补 squeeze 来矫正结果以对齐 pytorch,不是就可和 Pytorch 相同。直接使用 1-d Tensor 来表示 0-d Tensor, 就会导致这种情况下的 API 行为不一致。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

你要写一下上面torch的代码,以及paddle不支持0D下的写法、paddle支持0D下的写法,从而才好对比分析

无论是使用标量索引、切片还是 gather/scatter 等, 只要最终索引个数等于输入Tensor的维数, 就应当输出0维Tensor。下面的代码展示了这种情况:
在使用索引切片的时候,应当支持输入和输出是 0-d Tensor 的情况。

使用标量作为索引的时候, 输入0-D时,应该与int标量索引的效果一致,具有降维效果,以下是一个例子:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

分两个小标题:

  • 索引输入0D时
  • 索引输出0D时

这样看起来更清晰点

y = paddle.gather(x, idx, axis=0)
print(y.shape) # [2, 3, 2, 4]
```python
x = paddle.to_tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

用paddle.rand吧,shape看得更清楚

@AndSonder
Copy link
Contributor Author

@zhwesky2010 都按照要求修改啦

@AndSonder AndSonder requested a review from zhwesky2010 April 24, 2024 11:07


```python
import torch

x = torch.tensor(3.14)
out = torch.stack([x, x])
print(out.shape) # 输出 torch.Size([2]) 没有新增维度,符合预期
print(out.shape) # 输出 torch.Size([2]) 0D升为1D,符合预期
```

如果 Paddle 不支持 0-d Tensor 而是直接用 1-d Tensor 来表示, 就需要额外判断 x 是否为 1D,是就需要补 squeeze 来矫正结果以对齐 pytorch,不是就可和 Pytorch 相同。直接使用 1-d Tensor 来表示 0-d Tensor, 就会导致这种情况下的 API 行为不一致。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这段话换一下吧,重点要强调Paddle支持0D后的代码更清晰简洁

然后下面的两个示例代码最好分开写,分小标题:

  • 假如paddle不支持0D,则写法为:
    ...

  • 假如paddle支持0D,则写法为:
    ...


### 3.5 索引切片操作

在使用索引切片的时候,应当支持输入和输出是 0-d Tensor 的情况。

使用标量作为索引的时候, 输入0-D时,应该与int标量索引的效果一致,具有降维效果,以下是一个例子:

- 索引输入0D时:使用标量作为索引的时候,输入0-D时,应该与int标量索引的效果一致,具有降维效果,以下是一个例子:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个例子的输出,也用一样的x=paddle.rand([2, 2, 2]),好对比

@AndSonder AndSonder requested a review from zhwesky2010 April 28, 2024 12:14
@AndSonder
Copy link
Contributor Author

@zhwesky2010 已经都修改了,麻烦研发老师再看一下 ~

@@ -56,28 +56,37 @@ out = torch.stack([x, x])
print(out.shape) # 输出 torch.Size([2]) 0D升为1D,符合预期
```

如果 Paddle 不支持 0-d Tensor 而是直接用 1-d Tensor 来表示, 就需要额外判断 x 是否为 1D,是就需要补 squeeze 来矫正结果以对齐 pytorch,不是就可和 Pytorch 相同。直接使用 1-d Tensor 来表示 0-d Tensor, 就会导致这种情况下的 API 行为不一致。
如果 Paddle 不支持 0-d Tensor 而是直接用 1-d Tensor 来表示, 就需要额外判断 x 是否为 1D,是就需要补 squeeze 来矫正结果以对齐 pytorch,不是就可和 Pytorch 相同。支持 0-D 的 paddle 可以有更更加简洁的代码实现。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

如果 Paddle 不支持 0-d Tensor,就需要额外判断 x 是否为 1D,然后补squeeze来矫正结果,这造成了代码的冗余与可读性降低。写法如下:
...

如果 Paddle 支持 0-d Tensor,就无需增加这些额外判断的代码,代码可与其他深度学习框架(例如Pytorch)完全一致。写法如下:
...

由上可看出,支持0-d Tensor后的Paddle代码,在写法上简洁清晰很多,提升了用户体验与API易用性。

@AndSonder
Copy link
Contributor Author

@zhwesky2010 已修改,研发老师辛苦了

@AndSonder AndSonder requested a review from zhwesky2010 April 28, 2024 12:24
Copy link
Contributor

@zhwesky2010 zhwesky2010 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@luotao1 luotao1 merged commit e1a0c2e into PaddlePaddle:master Apr 29, 2024
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants